package com.guang.syncronized.syncronizedbatchrevoke;

import com.guang.syncronized.domain.ObjectAge;
import org.openjdk.jol.info.ClassLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Description 测试对象的年龄的时候可以设置参数：-Xmx100m -Xms100m
 * @Author liguang
 * @Date 2022/10/20/10:28
 */
public class BatchRevokeTestOne {
    private final static Logger logger = LoggerFactory.getLogger(BatchRevokeTestOne.class);

    public static void main(String[] args) throws InterruptedException {
        List<Abc> abcList = new ArrayList<>();
        // 为了让对象头中呈现出无锁可偏向
        TimeUnit.SECONDS.sleep(5);

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 200; i++) {
                Abc abc = new Abc();
                // 让abc对象都偏向t1线程
                synchronized (abc) {
                    abcList.add(abc);
                }
            }

            // 为了不让线程ID复用
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t1");
        t1.start();
        // 为了让线程t1先启动
        TimeUnit.MICROSECONDS.sleep(10);

        Thread t2 = new Thread(() -> {
            int cout = 1;
            for (Abc abc : abcList) {
                synchronized (abc) {
                    // 应该是轻量级锁了！但是依然是偏向锁前几个是轻量级锁，而后面的将成为偏向锁
                    if (cout == 15) {
                        logger.info("当前对象是list集合中的第{}个对象，应该是轻量锁000，对应的对象头是：{}", cout + 1, ClassLayout.parseInstance(abc).toPrintable());
                    }
                    // 20之后的就应该是批量锁撤销
                    if (cout == 20) {
                        logger.info("当前对象是list集合中的第{}个对象，应该是偏向锁101，对应的对象头是：{}", cout, ClassLayout.parseInstance(abc).toPrintable());
                        return;
                    }
                }
                cout++;
            }
        }, "t2");
        t2.start();
        t2.join();
        logger.info("再次将当前类的对象进行偏向");
        // 但是如果此时锁对象仍然有偏向其他线程了的，那么就会导致40之后的升级到轻量级锁
        // 批量撤销
        new Thread(() -> {
            int count = 1;
            for (int i = 0; i < abcList.size(); i++) {
                Abc abc = abcList.get(i);
                synchronized (abc){
                    if (count==15){
                        logger.info("count为：{},应该是偏向锁101，对应的对象头是：{}", count,ClassLayout.parseInstance(abc).toPrintable());
                    }
                    if (count==25){
                        logger.info("count为：{},应该是轻量级锁000，对应的对象头是：{}",count, ClassLayout.parseInstance(abc).toPrintable());
                    }
                    if (count==70){
                        logger.info("count为：{},应该是轻量级锁000，对应的对象头是：{}",count, ClassLayout.parseInstance(abc).toPrintable());
                        return;
                    }
                }
                count++;
            }
        }, "t3").start();
    }
}
